﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using Wf5.Engine;
using Wf5.Engine.Common;
using Wf5.Engine.Utility;

using FCDB.Entity;
using FCDB.Entity.EntityEx;

namespace Wf5.Engine.Business
{
    /// <summary>
    /// 工作流服务（数据查询）
    /// </summary>
    public partial class WorkflowService : IWorkflowService
    {
        #region 获取流程实例、活动实例和转移实例数据的获取
        /// <summary>
        /// 获取流程实例数据
        /// </summary>
        /// <param name="processInstanceID"></param>
        /// <returns></returns>
        public WfProcessInstance GetProcessInstance(int processInstanceID)
        {
            var pim = new ProcessInstanceManager();
            var instance = pim.GetById(processInstanceID);
            return instance;
        }

        /// <summary>
        /// 获取活动实例数据
        /// </summary>
        /// <param name="activityInstanceID"></param>
        /// <returns></returns>
        public WfActivityInstance GetActivityInstance(int activityInstanceID)
        {
            var aim = new ActivityInstanceManager();
            var instance = aim.GetById(activityInstanceID);
            return instance;
        }

        /// <summary>
        /// 获取当前等待办理节点的任务分配人列表
        /// </summary>
        /// <param name="runner"></param>
        /// <returns></returns>
        public IList<Performer> GetTaskPerformers(WfAppRunner runner)
        {
            var tm = new TaskManager();
            var tasks = tm.GetReadyTaskOfApp(runner).ToList();

            Performer performer;
            IList<Performer> performerList = new List<Performer>();
            foreach (var task in tasks)
            {
                performer = new Performer(task.AssignedToUserID, task.AssignedToUserName);
                performerList.Add(performer);
            }
            return performerList;
        }
       public   IList<WfActivityInstanceTasksEx> GetNextTask(TaskQueryEntity query)
        {
            int allRowsCount = 0;
            var taskManager = new TaskManager();
            return taskManager.GetRunningTasksByCreateUser(query, out allRowsCount).ToList();
        }
        /// <summary>
        /// 返回当前运行节点的Map信息
        /// </summary>
        /// <param name="runner"></param>
        /// <returns></returns>
        public CurrentRunningNodeMap GetRunningMap(WfAppRunner runner)
        {
            CurrentRunningNodeMap nodeMap = new CurrentRunningNodeMap();
            IList<CurrentRunningNodeMapComplex> runningList = new List<CurrentRunningNodeMapComplex>();

            //先判断流程状态
            //如果流程记录为空，说明流程未启动，返回空对象
            var pim = new ProcessInstanceManager();
            var processInstance = pim.GetProcessInstanceLatest(runner.AppName, runner.AppInstanceID, runner.ProcessGUID);
            if (processInstance == null)
            {
                nodeMap.ProcessState = ProcessStateEnum.NotStart;
                return nodeMap;
            }

            nodeMap.ProcessState = (ProcessStateEnum)processInstance.ProcessState;

            //流程流程状态为正常结束，则返回结束人信息
            if (processInstance.ProcessState == (short)ProcessStateEnum.Completed)
            {
                nodeMap.EndUser = new WfLogonUser(processInstance.EndedByUserID.Value, processInstance.EndedByUserName);
                return nodeMap;
            }

            //其它非正常运行状态，直接返回
            if (processInstance.ProcessState != (short)ProcessStateEnum.Running)
            {
                return nodeMap;
            }

            //如果流程在运行状态，则返回运行时信息
            var aim = new ActivityInstanceManager();
            var activityList = aim.GetProcessRunningActivityList(runner.AppInstanceID,
                runner.ProcessGUID).ToList();

            if (activityList == null || activityList.Count == 0)
            {
                return null;
            }

            if (activityList.Count > 1)
            {
                var e = new WorkflowException(string.Format("当前流程有多个节点处于运行状态，会引起应用数据的不正常处理，运行节点个数：{0}!",
                    activityList.Count));
                LogManager.RecordLog("获取当前运行节点Map信息异常", LogEventType.Exception, LogPriority.Normal, runner, e);

                throw e;
            }

            var runningNode = activityList[0];
            var nodeMapComplex = aim.GetCurrentRunningNodeMap(runningNode, runner);

            if (nodeMapComplex.PreviousActivityInstance.Count > 1)
            {
                var e = new WorkflowException(string.Format("当前运行节点有多个上游节点，有可能会引起应用数据的不正常处理，上游节点个数：{0}!",
                    nodeMapComplex.PreviousActivityInstance.Count));
                LogManager.RecordLog("获取当前运行节点Map信息异常", LogEventType.Exception, LogPriority.Normal, runner, e);

                throw e;
            }

            var previousNode = nodeMapComplex.PreviousActivityInstance.Count == 1? nodeMapComplex.PreviousActivityInstance[0] : null;
            nodeMap = CurrentRunningNodeMap.Instance(runningNode,
                nodeMapComplex.IsMine,
                previousNode,
                nodeMapComplex.NextActivityTree);

            return nodeMap;
        }
        #endregion

        #region 合并分支完全模式下的当前运行节点Map信息
        ///// <summary>
        ///// 获取当前节点的Map信息
        ///// 备注：留在后来的完全复杂模式下运行
        ///// </summary>
        ///// <param name="runner"></param>
        ///// <returns></returns>
        //internal IList<CurrentRunningNodeMap> GetCurrentRunningActivityMap(WfAppRunner runner)
        //{
        //    CurrentRunningNodeMap node = null;
        //    IList<CurrentRunningNodeMap> runningList = new List<CurrentRunningNodeMap>();

        //    var aim = new ActivityInstanceManager();
        //    ISession session = SessionFactory.CreateSession();
        //    var activityList = aim.GetProcessRunningActivityList(runner.AppInstanceID,
        //        runner.ProcessGUID,
        //        session);

        //    foreach (var entity in activityList)
        //    {
        //        node = aim.GetCurrentRunningNodeMap(entity, runner);
        //        runningList.Add(node);
        //    }

        //    return runningList;
        //}
        #endregion
    }
}
